package com.wuzhishan.news.service.Impl;

import com.wuzhishan.news.mapper.*;
import com.wuzhishan.news.pojo.*;
import com.wuzhishan.news.service.articleService;
import com.wuzhishan.news.utils.EhcacheUtil;
import com.wuzhishan.news.utils.numberTransUtil;
import com.wuzhishan.news.utils.strengthArticle;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class articleServiceImpl implements articleService {
    @Autowired
    private articleMapper mapper;
    @Autowired
    private groupMapper Gmapper;
    @Autowired
    private commentMapper commentMapper;
    @Autowired
    private userMapper userMapper;
    @Autowired
    private favorMapper favorMapper;
    //推荐的页面(递增顺序)
    private static int recommendPage = 0;

    @Override
    public ModelAndView getAll(String id, String ord, String page, String Size, ModelAndView mv) {
        PageBean pageBean = new PageBean();
        //设置分页的当前索引和页面大小
        int currentPage = Integer.parseInt(page);
        int pageSize = Integer.parseInt(Size);
        int pageIndex = (currentPage-1)*pageSize;
        //设置按照发布时间还是热度进行排序
        String sortBy = null;
        if("newest".equals(ord)){
            //按时间排序
            sortBy = "ba.create_time";
        }else if("hottest".equals(ord)){
            //按照热度排序
            sortBy = "ba.hits";
        }else {
            sortBy = "ba.create_time";
        }
        int totalCount = mapper.getCount(id, sortBy, pageIndex, pageSize);
        pageBean.setTotalCount(totalCount);
        pageBean.setTotalPage(totalCount%pageSize==0?totalCount/pageSize:totalCount/pageSize+1);
        pageBean.setCurrentPage(currentPage);
        pageBean.setPageSize(pageSize);
        //用于进行分页操作，数据通过list进行展示
        mv.addObject("pageBean",pageBean);
        /**
         * 将当前页文章数据缓存
         * 用Ehcache做缓存操作，防止高并发问题
         */
        List<BlogArticle> articles = (List<BlogArticle>) EhcacheUtil.get("Cache1","Articles"+currentPage);
        if (articles == null){
            articles = mapper.getAll(id, sortBy, pageIndex, pageSize);
            EhcacheUtil.put("Cache1","Articles"+currentPage,articles,5,5);
        }
        //用于前台进行数据展示
        List<ArticleVo> list = new ArrayList<>();
        for (BlogArticle article : articles) {
            ArticleVo vo = new ArticleVo();
            /**
             *将当前文章评论数缓存，防止高并发问题
             * 使用Ehcache做缓存
             */
            Integer counts = EhcacheUtil.get("Cache1","articleComments");
            if (counts == null){
                counts = commentMapper.countsOfArticle(article.getId());
                vo.setComments(counts);
                EhcacheUtil.put("Cache1","articleComments",counts,5,5);
            }
            /**
             *当前文章喜欢数缓存，防止高并发
             * 使用Ehcache做缓存
             */
            Integer likes = EhcacheUtil.get("Cache1","likes");
            if (likes == null){
                likes = favorMapper.articleFavors(article.getId());
                vo.setLikes(likes);
                EhcacheUtil.put("Cache1","likes",likes,5,5);
            }
            BeanUtils.copyProperties(article,vo);
            list.add(vo);
        }
        mv.addObject("articles",list);
        return mv;
    }

    @Override
    public void addArticle(String title, String group, String content, BlogUser user) {
        //获取当前板块信息
        BlogGroup bGroup = Gmapper.getOneById(group);
        //将文章信息放入文章实体
        BlogArticle article = new BlogArticle();
        article.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        article.setTitle(title);
        article.setHits(0);
        article.setContent(content);
        article.setGroup(bGroup);
        article.setUser(user);
        //调用dao层方法实现文章的插入
        mapper.add(article);
    }

    @Override
    public ModelAndView getArticleById(String articleId, ModelAndView mv) {
        //去除articleId千分位分隔符
        articleId = numberTransUtil.TransNum(articleId);
        BlogArticle article = mapper.getArticleById(articleId);
        BlogUser author = userMapper.getOneById(article.getUser().getId());
        int articleCount = mapper.countArticleOfUser((int) article.getUser().getId());
        int commentCount = commentMapper.countsOfArticle(Long.parseLong(articleId));
        int favorCount = favorMapper.articleFavors(Long.parseLong(articleId));
        //返回文章对应信息
        mv.addObject("articleInfo",article);
        //返回文章作者信息
        mv.addObject("author",author);
        //返回作者文章数目
        mv.addObject("articleCount",articleCount);
        //返回文章评论总条数
        mv.addObject("commentCount",commentCount);
        //返回文章喜欢总数
        mv.addObject("favorCount",favorCount);
        return mv;
    }
/**
 * 推荐功能实现流程
 *1、查询我的喜欢表
 * 2、根据查询出来的项目找出他们之间的编号，并判断编号一致的有多少，多大的比例
 * 3、比例乘上默认的推荐文章目，然后就是推荐这类文章的数目。
 * 4、根据数目查找对应文章类别的文章并返回给前端展示
 * 5、注：默认每次更新5篇文章。
 */

    /**
     * 推荐功能实现
     * @param groupId
     * @param ord
     * @param page
     * @param pageSize
     * @param mv
     * @return
     */
    @Override
    public ModelAndView recommend(String groupId, String ord, String page, String pageSize,long userId, ModelAndView mv) {
        //没执行一次推荐，推荐的页面加一，使得不会出现推荐重复的情况。
        int pageIndex = recommendPage++ * 8;    //计算出推荐文章的开始索引
        int blogCount = 0;  //喜欢博文文章的数量
        int cCount = 0;     //喜欢C++社区文章的数量
        List<BlogFavor> favorList = favorMapper.getFavorByUserId(userId);
        for (BlogFavor favor : favorList) {
            BlogArticle article = mapper.getArticleById(String.valueOf(favor.getArticle().getId()));
            if (article.getGroup().getId() == 4)
                cCount++;
            else if (article.getGroup().getId() == 3){
                blogCount++;
            }
        }
        blogCount = (int) ((float)blogCount/(blogCount + cCount) * 8);                  //推荐博文文章的数量
        cCount = 8 - blogCount;                         //推荐C++文章的数量

        List<BlogArticle> blogs = mapper.getRecommend(3,pageIndex,blogCount);   //博文的推荐列表
        List<BlogArticle> articles = mapper.getRecommend(4,pageIndex,cCount);   //C++内容的推荐列表
        for (BlogArticle blog : blogs) {
            articles.add(blog);
        }
        //数据再封装，将文章的喜欢数和评论数加上
        List<ArticleVo> list = new ArrayList<>();
        for (BlogArticle article : articles) {
            ArticleVo vo = new ArticleVo();
            Integer counts = commentMapper.countsOfArticle(article.getId());
            vo.setComments(counts);
            Integer likes = favorMapper.articleFavors(article.getId());
            vo.setLikes(likes);
            BeanUtils.copyProperties(article,vo);
            list.add(vo);
        }
        mv.addObject("articles",list);
        mv.addObject("pageBean",null);
        return mv;
    }

    /**
     * 模糊搜索文章
     * @param word
     * @param page
     * @param pSize
     * @param mv
     * @return
     */
    @Override
    public ModelAndView search(String word, String page, String pSize, ModelAndView mv) {
        //将word前后加上%实现模糊查询
        word = "%"+word+"%";
        //设置分页参数
        PageBean pageBean = new PageBean();
        //设置分页的当前索引和页面大小
        int currentPage = Integer.parseInt(page);
        int pageSize = Integer.parseInt(pSize);
        int pageIndex = (currentPage-1)*pageSize;
        int totalCount = mapper.searchCount(word);
        pageBean.setTotalCount(totalCount);
        pageBean.setTotalPage(totalCount%pageSize==0?totalCount/pageSize:totalCount/pageSize+1);
        pageBean.setCurrentPage(currentPage);
        pageBean.setPageSize(pageSize);
        //用于进行分页操作，数据通过list进行展示
        mv.addObject("pageBean",pageBean);
        //模糊查询对应文章
        List<BlogArticle> articles = mapper.searchArticle(word, pageIndex, pageSize);
        //增强文章实体，给文章增加评论和点赞数
        List<ArticleVo> list = new ArrayList<>();
        for (BlogArticle article : articles) {
            ArticleVo vo = new ArticleVo();
            //获取对应文章评论数
            int counts = commentMapper.countsOfArticle(article.getId());
            vo.setComments(counts);
            //获取对应文章点赞数
            int likes = favorMapper.articleFavors(article.getId());
            vo.setLikes(likes);
            BeanUtils.copyProperties(article,vo);
            list.add(vo);
            System.out.println(vo);
        }
        mv.addObject("articles",list);
        return mv;
    }

    /**
     * 点击文章详情页，文章阅读量加一
     * @param articleId
     */
    @Override
    public void hitPlus(String articleId) {
        mapper.hitPlus(articleId);
    }
}
